package org.person.gift.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import org.apache.rocketmq.client.producer.TransactionSendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.person.gift.constants.GiftConstants;
import org.person.gift.domain.GoodsSpu;
import org.person.gift.dto.GiftOnsaleMsgQueueDto;
import org.person.gift.exception.ResponseCode;
import org.person.gift.exception.SystemAssert;
import org.person.gift.mapper.GoodsSpuMapper;
import org.person.gift.service.IGoodsSpuService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * spu表 服务实现类
 * </p>
 *
 * @author MaxPeng
 * @since 2024-02-15
 */
@Service
public class GoodsSpuServiceImpl extends ServiceImpl<GoodsSpuMapper, GoodsSpu> implements IGoodsSpuService {
    @Autowired
    private GoodsSpuMapper goodsSpuMapper;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Override
    public String onsale(List<Long> ids) {
        //1.对前端的id集合做非空校验
        SystemAssert.isNotNull(ids, ResponseCode.RESPONSE_CODE_40028);
        //2.通过id集合查询数据库中符合上架要求的货品数据；（需要是下架3或者审核通过1货品数据才能上架）
        List<GoodsSpu> goodsSpus = super.selectBatchIds(ids);
        goodsSpus = goodsSpus.stream().filter(x -> (x.getState() == 1 || x.getState() == 3)).collect(Collectors.toList());
        SystemAssert.isNotNull(goodsSpus,ResponseCode.RESPONSE_CODE_40028);
        //将状态改为上架->2，将上架时间更新
        //集合消息对象中需要发送的内容
        List<GiftOnsaleMsgQueueDto> giftOnsaleMsgQueueDtos = new ArrayList<>();
        goodsSpus.forEach(x -> {
            GiftOnsaleMsgQueueDto msgQueueDto = new GiftOnsaleMsgQueueDto();
            BeanUtils.copyProperties(x,msgQueueDto);
            msgQueueDto.setBrandName("香奈儿");
            msgQueueDto.setCategoryName("香水");
            msgQueueDto.setTenantName("太古里化妆店");
            msgQueueDto.setCommentCount(0);
            msgQueueDto.setSaleCount(0);
            msgQueueDto.setSkuProperties("");
            msgQueueDto.setSkuProperties("");
            msgQueueDto.setOnsaleTime(new Date());
            giftOnsaleMsgQueueDtos.add(msgQueueDto);
        });
        //返回前端内容，成功处理了多少条，失败了多少条
        String msg = "一共选择了%s条数据/成功上架%s条/失败%s条";
        msg = String.format(msg,ids.size(),goodsSpus.size(),ids.size()-goodsSpus.size());
        //3.在本地事务中修改符合上架条件的商品信息 @TODO
        //4.将数据内容封装到消息中，由生产者转发给消息队列
        //事务消息发送，具体四个参数
        //1.生产组名    2.topic+tag     3.消息对象      4.扩散参数，可以不传
        String txProducerGroup = GiftConstants.GIFT_ONSALE_TX_PRODUCER_GROUP;
        String destination = GiftConstants.GIFT_ONSALE_TX_TOPIC + ":" + GiftConstants.GIFT_ONSALE_TX_TAG;
        String msgContext = JSONArray.toJSONString(giftOnsaleMsgQueueDtos);
        Message<String> message = MessageBuilder.withPayload(msgContext).build();
        TransactionSendResult sendResult = rocketMQTemplate.sendMessageInTransaction(txProducerGroup, destination, message, null);
        System.out.println(sendResult);
        return msg;
    }

    @Override
    public String offsale(List<Long> ids) {
        //1.对前端的id集合做非空校验
        SystemAssert.isNotNull(ids, ResponseCode.RESPONSE_CODE_40029);
        //2.通过集合查询满足下架条件的商品信息（只需要取id即可）；必须是上架商品才能下架
        List<GoodsSpu> goodsSpus = super.selectBatchIds(ids);
        goodsSpus = goodsSpus.stream().filter(x -> x.getState()==2).collect(Collectors.toList());
        SystemAssert.isNotNull(goodsSpus, ResponseCode.RESPONSE_CODE_40029);
        String msg = "一共选择了%s条数据/成功下架%s条/失败%s条";
        msg = String.format(msg,ids.size(),goodsSpus.size(),ids.size()-goodsSpus.size());
        //3.本地事务更改符合条件的商品信息，状态改为下架，更新下架时间
        List<Long> offsaleIds = goodsSpus.stream().map(GoodsSpu::getId).collect(Collectors.toList());
        //4.下架商品的id集合封装为消息数据体，然后指定topic发送事务消息
        String txProducerGroup = GiftConstants.GIFT_OFFSALE_TX_PRODUCER_GROUP;
        String destination = GiftConstants.GIFT_OFFSALE_TX_TOPIC + ":" + GiftConstants.GIFT_OFFSALE_TX_TAG;
        String msgContext = JSONArray.toJSONString(offsaleIds);
        Message<String> message = MessageBuilder.withPayload(msgContext).build();
        rocketMQTemplate.sendMessageInTransaction(txProducerGroup,destination,message,null);
        return msg;
    }

    /**
     * 上架本地事务
     * @param spuOnsaleDtos
     * @return
     */
    @Override
    @Transactional
    public boolean executeOnsaleLocalTransactionOpr(List<GiftOnsaleMsgQueueDto> spuOnsaleDtos) {
        try {
            //获取传递集合中的id组成的集合
            List<Long> spuNos = spuOnsaleDtos.stream().map(GiftOnsaleMsgQueueDto::getSpuNo).collect(Collectors.toList());
            goodsSpuMapper.onsale(spuNos,GiftConstants.GIFT_ONSALE.longValue());
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     *
     * 上架回查
     * @param spuNo
     * @return
     */
    @Override
    public boolean checkExsitOnsaled(Long spuNo) {
        Integer integer = goodsSpuMapper.selectCount(new EntityWrapper<GoodsSpu>()
                .eq("spu_no", spuNo)
                .and()
                .eq("state", GiftConstants.GIFT_OFFSALE.longValue())
                .or()
                .eq("state", GiftConstants.GIFT_AUDIT_SUCCESS.longValue())
        );
        return integer > 0;
    }


    @Override
    @Transactional
    public boolean executeOffsaleLocalTransactionOpr(List<Long> offsaleIds) {
        try {
            goodsSpuMapper.offsale(offsaleIds,GiftConstants.GIFT_OFFSALE.longValue());
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public boolean checkExsitOffsaled(List<Long> offsaleIds) {
        List<GoodsSpu> goodsSpus = goodsSpuMapper.selectList(new EntityWrapper<GoodsSpu>()
                .in("id", offsaleIds)
                .and()
                .eq("state", GiftConstants.GIFT_ONSALE)
        );
        return goodsSpus.size()>0;
    }
}
